import { Msgerror, Msginfo, Msgsuccess, Msgwarning } from "@ct0/icons";
import Notification from "rc-notification";
import {
  NotificationInstance,
  NotificationProps,
} from "rc-notification/lib/Notification";
import React from "react";
import type { MessageNoticeConfig } from "./type";

export default { success, warning, error, info, destroy };

let notificationInstance: NotificationInstance | null = null;

type MessageText = string | React.ReactNode;

const IconComponent = {
  info: Msginfo,
  error: Msgerror,
  success: Msgsuccess,
  warning: Msgwarning,
};

type ArgsProps = NotificationProps & {
  getContainer?: () => HTMLElement;
};

function getNoticeInstance(
  args: ArgsProps,
  callback: (instance: NotificationInstance) => void
) {
  if (notificationInstance) {
    callback(notificationInstance);
    return;
  }
  Notification.newInstance(args, (instance) => {
    //处理事件循环（宏任务）注销的情况
    if (notificationInstance) {
      callback(notificationInstance);
      return;
    }
    notificationInstance = instance;

    callback(instance);
  });
}

function notice(text: MessageText, config: MessageNoticeConfig) {
  const { duration = 3, type } = config;
  //  如果是一个 JSON 对象，则要先序列化
  if (text?.constructor.name == "Object") text = JSON.stringify(text);

  return new Promise((r) => {
    const key = new Date().getTime();
    const Icon = IconComponent[type];

    getNoticeInstance({ maxCount: 5, prefixCls: "ct0-message" }, (instance) => {
      instance.notice({
        key,
        className: `ct0-message-${type}`,
        duration,
        content: (
          <div className="ct0-message-custom-content">
            <Icon className="ct0-message-icon" />
            <span>{text}</span>
          </div>
        ),
        onClose() {
          r(true);
        },
      });
    });
  });
}

function success(text: MessageText, duration?: number) {
  return notice(text, { type: "success", duration });
}

function info(text: MessageText, duration?: number) {
  return notice(text, { type: "info", duration });
}

function error(text: MessageText, duration?: number) {
  return notice(text, { type: "error", duration });
}

function warning(text: MessageText, duration?: number) {
  return notice(text, { type: "warning", duration });
}

function destroy() {
  notificationInstance?.destroy();
  notificationInstance = null;
}
